package com.example.shiro.config;


import com.auth0.jwt.JWT;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

@Configuration
@ConditionalOnProperty(prefix = "shiro",name = "model",matchIfMissing = false,havingValue = "jwt")
public class BearerShiroConfig {



    @Bean
    public Realm defaultRealm(){
        return new AuthorizingRealm() {
            @Override
            protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
                SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
                authorizationInfo.addStringPermission("*");
                return authorizationInfo;
            }

            @Override
            protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
                return new SimpleAuthenticationInfo("admin","123456",this.getClass().getName());
            }
        };
    }


    @Bean
    public Realm bearerRealm(){
        AuthorizingRealm realm = new AuthorizingRealm() {

            @Override
            protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
                SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
                authorizationInfo.addStringPermission("*");
                return authorizationInfo;
            }

            @Override
            protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
                //转换
                BearerToken bearerToken = (BearerToken) token;
                //前端添加到请求头上的token
                String bearer = bearerToken.getToken();
                //处理token，使用JWT的话直接解密就好
                ObjectMapper objectMapper = new ObjectMapper();
                try {
                    Map<String,String> py  = objectMapper.readValue(bearer, HashMap.class);
                    //返回认证信息后会和token的credentials比对一下，所以我们直接返回token的credentials
                    return new SimpleAuthenticationInfo(py.get("user"),token.getCredentials(),this.getClass().getName());
                } catch (JsonProcessingException e) {
                    throw new  AuthenticationException("token解析失败");
                }
            }
        };
        realm.setAuthenticationTokenClass(BearerToken.class);
        return realm;
    }


    @Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition(){
        DefaultShiroFilterChainDefinition shiroFilterChainDefinition = new DefaultShiroFilterChainDefinition();
        shiroFilterChainDefinition.addPathDefinition("/jwt/login","anon");
        shiroFilterChainDefinition.addPathDefinition("/shiro/**","anon");
        shiroFilterChainDefinition.addPathDefinition("/**","authcBearer");
        return shiroFilterChainDefinition;
    }
}
